/*
* File: GridpTask.java
* Author: Daniel Rogers
* Created on Jan 18, 2008
*
*/
package gri.gridp.tasks;
import gri.gridp.modules.Function;
import gri.tasks.Task;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.io.File;
import org.apache.log4j.Logger;
import gri.tasks.TaskDef;
/**
* An extension to the basic RunScriptTask which auto-generates the
* script to be executed from a GRIDP function and executes it via
* RunScriptTask. The input parameters for both the GRIDP script and
* the RunScriptTask are exposed as parameters for this task. We prefix
* all RunScriptTask parameters with "script:" so that they are easily
* identified.
*
* Any Task can be used for the script-running task. This task is
* expected to follow the conventions of RunScriptTask. Specifically,
* we expect the following parameters to be present:
*
* Input:
* RunScriptTask.SCRIPT
* RunScriptTask.SWORKDIR
* Output:
* RunScriptTask.OUTPUT_FILES
*
* @author dan.rogers
*/
public class GridpScriptTask implements Task {
static Logger logger = Logger.getLogger(GridpScriptTask.class);
// ---------------------------------------------------------- Properties
Task runScriptTask;
Function function;
TaskDef taskDef;
// ---------------------------------------------------------- Constructor
public GridpScriptTask(Function function, Task runScriptTask) {
this.function = function;
this.runScriptTask = runScriptTask;
this.taskDef = createTaskDef(function);
}
public TaskDef createTaskDef(Function function) {
//create TaskDef:
TaskDef baseTaskDef = runScriptTask.getTaskDef().copy();
baseTaskDef.removeInput(RunScriptTask.SCRIPT);
baseTaskDef.insertPrefix("script:");
TaskDefProvider provider = new BasicTaskDefProvider();
TaskDef gridpTaskDef = provider.createTaskDef(function);
//gridpTaskDef.insertPrefix("gridp:");
gridpTaskDef.extend(baseTaskDef);
return gridpTaskDef;
}
// ------------------------------------------------------ Implementation
/**
* Returns a ParameterizedTaskDef for this task.
*/
public TaskDef getTaskDef() {
return taskDef;
}
/**
* Executes the task.
*/
public Map execute(Map inputs) throws Exception {
//get workdir from script inputs:
String workdirParam = "script:" + RunScriptTask.WORKDIR;
File workdir = (File)inputs.get(workdirParam);
if (workdir == null) {
workdir = (File)taskDef.getInput(workdirParam).getDefaultValue();
inputs.put("script:workdir", workdir);
}
//separate parameters:
Map runScriptInputs = filter(inputs, "script:");
Map gridpInputs = inputs; //leftover inputs are for GRIDP
if (logger.isDebugEnabled()) {
logger.debug("Beginning GRIDP task execution");
logger.debug("RunScript parameters: " + Util.toString(runScriptInputs));
logger.debug("GridpScript parameters: " + Util.toString(gridpInputs));
}
//build script:
GridpScriptAssistant scriptAssistant = new GridpScriptAssistant(function, workdir);
String script = scriptAssistant.prepareScript(gridpInputs);
runScriptInputs.put("script", script); //This command prevents anyone from injecting a script
//execute:
if (logger.isDebugEnabled())
logger.debug("Executing GRIDP task");
Map outputs = runScriptTask.execute(runScriptInputs);
if (logger.isDebugEnabled())
logger.debug("Process started successfully");
//modify output (separate GRIDP outputs from others):
outputs = insertPrefix(outputs, "script:");
List outputFiles = (List)outputs.get("script:" + RunScriptTask.OUTPUT_FILES);
Map gridpOutputs = scriptAssistant.removeOutputs(outputFiles);
outputs.putAll(gridpOutputs);
return outputs;
}
/**
* Filters the given parameter map. Variables with the given prefix
* are removed from the map and stored in another one (which is returned).
* The prefix is removed during this process.
*/
public static Map filter(Map params, String prefix) {
//get names first (so we aren't modifying map as we traverse it)
List matches = new ArrayList(params.size());
Iterator paramNames = params.keySet().iterator();
while (paramNames.hasNext()) {
String paramName = (String)paramNames.next();
if (paramName.startsWith(prefix))
matches.add(paramName);
}
//filter map:
Map newParams = new HashMap(matches.size());
Iterator iMatches = matches.iterator();
while (iMatches.hasNext()) {
String paramName = (String)iMatches.next();
Object value = params.remove(paramName);
paramName = paramName.substring(prefix.length()); //remove prefix
newParams.put(paramName, value);
}
return newParams;
}
/**
* Creates a copy of the map with all parameter names prefixed
* with the given string.
*/
protected Map insertPrefix(Map params, String prefix) {
Map newParams = new HashMap(params.size());
Iterator iEntries = params.entrySet().iterator();
Map.Entry entry;
while (iEntries.hasNext()) {
entry = (Map.Entry)iEntries.next();
String paramName = (String)entry.getKey();
paramName = prefix + paramName;
newParams.put(paramName, entry.getValue());
}
return newParams;
}
}